/**
 * 六边形Mesh
 */

using GameBaseFramework.Base;
using System;
using System.Collections.Generic;
using GameBaseFramework.Extension;
using UnityEngine;
namespace GameGraphics.HomeWorld
{
    [RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
    public class HexMesh : MonoBehaviour
    {
        /// <summary>
        /// Hex Mesh
        /// </summary>
        private Mesh _hexMesh;
        /// <summary>
        /// collider
        /// </summary>
        private MeshCollider _meshCollider;
        /// <summary>
        /// 顶点数
        /// </summary>
        private List<Vector3> _vertices;
        /// <summary>
        /// 三角面
        /// </summary>
        private List<int> _triangles;
        /// <summary>
        /// 颜色
        /// </summary>
        private List<Color> _colors;
        /// <summary>
        /// 网格索引
        /// </summary>
        private HexGrid _hexGrids;

        /// <summary>
        /// 初始化
        /// </summary>
        public void Awake()
        {
            _meshCollider = gameObject.GetOrAddComponent<MeshCollider>();
            _meshCollider.enabled = true;
            _hexGrids = GetComponentInParent<HexGrid>();
            GetComponent<MeshFilter>().mesh = _hexMesh = new Mesh();
            _meshCollider.sharedMesh = _hexMesh;
            _hexMesh.name = "HexMesh";
            _vertices = new List<Vector3>();
            _triangles = new List<int>();
            _colors = new List<Color>();
        }

        /// <summary>
        /// 三角化所有单位
        /// </summary>
        /// <param name="cells"></param>
        public void Triangulate(List<HexCell> cells)
        {
            _hexMesh.Clear();
            _vertices.Clear();
            _triangles.Clear();
            _colors.Clear();
            for (int i = 0; i < cells.Count; i++)
            {
                Triangulate(cells[i]);
            }
            _hexMesh.vertices = _vertices.ToArray();
            _hexMesh.colors = _colors.ToArray();
            _hexMesh.triangles = _triangles.ToArray();
            _hexMesh.RecalculateNormals();
            _meshCollider.sharedMesh = _hexMesh;
        }

        /// <summary>
        /// 三角化单位
        /// </summary>
        /// <param name="cell"></param>
        private void Triangulate(HexCell cell)
        {
            var center = cell.LocalPosition;
            var color = cell.Color;
            int vertexIndex = _vertices.Count;
            _vertices.Add(center);
            _colors.Add(color);
            for (int i = 0; i < 6; i++)
            {
                _colors.Add(color);
                _triangles.Add(vertexIndex);
                _triangles.Add(vertexIndex + i + 1);
                _triangles.Add(vertexIndex + (i == 5 ? 1 : i + 2));
                //_vertices.Add(center + HexMetrics.GetCorner(i));
            }
            var v1 = center + HexMetrics.GetCorner(0);
            var v2 = center + HexMetrics.GetCorner(1);
            var v3 = center + HexMetrics.GetCorner(2);
            var v4 = center + HexMetrics.GetCorner(3);
            var v5 = center + HexMetrics.GetCorner(4);
            var v6 = center + HexMetrics.GetCorner(5);
            _vertices.Add(v1);
            _vertices.Add(v2);
            _vertices.Add(v3);
            _vertices.Add(v4);
            _vertices.Add(v5);
            _vertices.Add(v6);

            TriangulateConnection(cell, 0, 1, v1, v2, 0, 1);
            TriangulateConnection(cell, 1, 0, v2, v3, 1, 2);
            TriangulateConnection(cell, 1, -1, v3, v4, 2, 3);

        }

        /// <summary>
        /// 连接处
        /// </summary>
        private void TriangulateConnection(HexCell cell, int offsetR, int offsetS, Vector3 v1, Vector3 v2, int i, int j)
        {
            try
            {
                var neighbor = _hexGrids.GetNeighbor(cell, offsetR, offsetS);
                if (neighbor == null)
                {
                    return;
                }
                Color Color = GetConnectionColor(cell, neighbor);
                var color = cell.Color.a == 0 ? new Color(0, 0, 0, 0) : Color;
                Vector3 bridge = HexMetrics.GetBridge(i, j);
                Vector3 v3 = v1 + bridge;
                Vector3 v4 = v2 + bridge;
                AddQuad(v1, v2, v3, v4);
                AddQuadColor(color);

                if (i <= 1)
                {
                    var nextNeighbor = i == 0 ? _hexGrids.GetNeighbor(cell, 1, 0) : _hexGrids.GetNeighbor(cell, 1, -1);
                    if (nextNeighbor != null)
                    {
                        AddTriangle(v2, v4, v2 + HexMetrics.GetBridge(i + 1, j + 1));
                        AddTriangleColor(color);
                    }
                }
            }
            catch (Exception e)
            {
                DebugTool.LogException(e);
            }
        }

        /// <summary>
        /// 根据两个六边形的状态计算边缘的状态，确定边缘颜色
        /// </summary>
        /// <param name="cell"></param>
        /// <param name="neighbor"></param>
        /// <returns></returns>
        private Color GetConnectionColor(HexCell cell, HexCell neighbor)
        {
            var Status = Math.Max((int)cell.State, (int)neighbor.State);
            Color color;
            switch (Status)
            {
                case 0:
                    {
                        color = _hexGrids.BridgeIdleColor;
                        break;
                    }
                case 1:
                    {
                        color = _hexGrids.BridgeHoveredColor;
                        break;
                    }
                case 2:
                    {
                        color = _hexGrids.BridgeHoveredColor;
                        break;
                    }
                case 3:
                    {
                        color = _hexGrids.BridgeSelectedColor;
                        break;
                    }
                default:
                    {
                        color = Color.black;
                        break;
                    }
            }
            return color;
        }

        /// <summary>
        /// 添加三角面
        /// </summary>
        private void AddTriangle(Vector3 v1, Vector3 v2, Vector3 v3)
        {
            int vertexIndex = _vertices.Count;
            _vertices.Add(v1);
            _vertices.Add(v2);
            _vertices.Add(v3);
            _triangles.Add(vertexIndex);
            _triangles.Add(vertexIndex + 1);
            _triangles.Add(vertexIndex + 2);
        }

        /// <summary>
        /// 给三角形添加颜色
        /// </summary>
        private void AddTriangleColor(Color color)
        {
            _colors.Add(color);
            _colors.Add(color);
            _colors.Add(color);
        }

        /// <summary>
        /// 添加四边形
        /// </summary>
        private void AddQuad(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4)
        {
            int vertexIndex = _vertices.Count;
            _vertices.Add(v1);
            _vertices.Add(v2);
            _vertices.Add(v3);
            _vertices.Add(v4);
            _triangles.Add(vertexIndex);
            _triangles.Add(vertexIndex + 2);
            _triangles.Add(vertexIndex + 1);
            _triangles.Add(vertexIndex + 1);
            _triangles.Add(vertexIndex + 2);
            _triangles.Add(vertexIndex + 3);
        }

        /// <summary>
        /// 给四边形添加颜色
        /// </summary>
        private void AddQuadColor(Color color)
        {
            _colors.Add(color);
            _colors.Add(color);
            _colors.Add(color);
            _colors.Add(color);
        }
    }
}